package sk.xorty.si;

import org.springframework.integration.Message;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.annotation.CorrelationStrategy;
import org.springframework.integration.annotation.ReleaseStrategy;
import org.springframework.stereotype.Component;
import sk.xorty.oxm.*;

import java.util.List;

/**
 *  Consolidates all messages before sending them to the next 
 *  process. In our case, the next process is a web service call.
 *  <p>
 *  This aggregator has the following behavior:
 *  <pre>
 *  1. Correlates messages based on the correlation id.
 *  The correlation id is auto-generated by Spring. 
 *  
 *  2. Messages are released once all the total messages have reached
 *  the total sequence size. The sequence size is  auto-generated by Spring. 
 *  
 *  3. Once released, the messages are added to a Record instance which
 *  is added to an instance of AddListRequest. This AddListRequest is the final
 *  message we send to the web service. JAXB will marshall this object to XML
 *  before sending to an external web service.
 *  </pre>
 *  @author Krams at http://krams915@blogspot.com
 */
@Component
public class ProductAggregator {

    @Aggregator
	@SuppressWarnings("unchecked")
	public AddListRequest send(List<Message<?>> reqlist) {
        System.out.println("======== AGGREGATING MESSAGES ========");
        System.out.println("\t=> Total messages to send: " + reqlist.size());
		
		AddListRequest request = new AddListRequest();
		
		for (Message<?> mess: reqlist) {
			// Verify first if record is valid. A filter is run for each record
			// Invalid records have the property valid = false
			if ( Boolean.valueOf(mess.getHeaders().get("valid").toString()) ) {
				Record record = new Record();
				Entity entity = (Entity) mess.getPayload();
				
				if ( entity.getKeyword().equals(MessageTypes.TYPE_SALES)) {
					record.setSales((Sales) mess.getPayload());
					request.getRecord().add(record);
                    System.out.println("\t=> Added Sales");
				}
				
				if ( entity.getKeyword().equals(MessageTypes.TYPE_INVENTORY)) {
					record.setInventory((Inventory) mess.getPayload());
					request.getRecord().add(record);
                    System.out.println("\t=> Added Inventory");
				}
				
				if ( entity.getKeyword().equals(MessageTypes.TYPE_ORDER)) {
					record.setOrder((Order) mess.getPayload());
					request.getRecord().add(record);
                    System.out.println("\t=> Added Order");
				}
			}
		}
		
		return request;
	}

    @ReleaseStrategy
	public boolean release(List<Message<?>> messages) {
        return messages.size() == messages.get(0).getHeaders().getSequenceSize();
    }

    @CorrelationStrategy
	public String correlate(Message<?> message) {
		return message.getHeaders().getCorrelationId().toString();
	}
}
